说明:
错误处理是响应错误以及从错误中恢复的过程。可选类型可用来表示值缺失,但是当某个操作失败时,最好能得知失败的原因,从而可以作出相应的应对。
扩展:Swift中的错误处理涉及到错误处理模式,这会用到Cocoa和Objective-C中的NSError
18.1 表示并抛出错误
说明:错误用符合
ErrorType协议的类型的值来表示。这个空协议表明该类型可以用于错误处理。
技巧:Swift 的枚举类型尤为适合构建一组相关的错误状态,枚举的关联值还可以提供错误状态的额外信息。
1 | // 自动贩卖机错误 |
18.2 处理错误
说明:某个错误被抛出时,附近的某部分代码必须负责处理这个错误。有
4中给处理错误的方式
- 把函数
抛出的错误传递给调用此函数的代码- 用
do-catch语句处理错误- 将错误作为
可选类型处理断言此错误根本不会发生标识可能出错的地方:在调用一个能抛出错误的
函数、方法或者构造器之前,加上try关键字,或者try?或try!这种变体引伸:和其他语言中的异常处理不同的是,Swift 中的错误处理并不涉及解除调用栈,就此而言,
throw语句的性能特性是可以和return语句相媲美的。
18.2.1 用throwing函数传递错误
说明:一个标有
throws关键字的函数被称作throwing 函数。
- 调用
throwing函数必须使用try- 调用
throwing函数必须要么直接处理这些错误(使用do-catch语句,try?或try!);要么继续将这些错误传递下去用途:可以在其内部抛出错误,并将错误传递到函数
被调用时的作用域。
语法:在函数声明的参数列表和->之间加上throws关键字。
1 | func canThrowErrors() throws -> String |
注意:只有
throwing函数可以传递错误。任何在某个非 throwing 函数内部抛出的错误只能在函数内部处理。
1 | // 自动贩卖机错误 |
18.2.2 用Do-Catch处理错误
说明:可以使用一个
do-catch语句运行一段闭包代码来处理错误。如果在do子句中的代码抛出了一个错误,这个错误会与catch子句做匹配,从而决定哪条子句能处理它。
- 在
catch后面写一个匹配模式来表明这个子句能处理什么样的错误- 如果一条
catch子句没有指定匹配模式,那么这条子句可以匹配任何错误,并且把错误绑定到一个名字为error的局部常量catch子句不必将do子句中的代码所抛出的每一个可能的错误都作处理- 如果所有
catch子句都未处理错误,错误就会传递到周围的作用域(要么是一个外围的do-catch错误处理语句,要么是一个throwing函数的内部)
1 | // 创建一个售卖机实例 |
18.2.3 将错误转换成可选值
语法:
try?
说明:使用try?调用表达式,返回相应表达式返回值的可选类型(如果表达式抛出错误,则表达式nil)
技巧:如果你想对所有的错误都采用同样的方式来处理,用try?就可以让你写出简洁的错误处理代码
1 | // throwing 函数 |
1 | // 从磁盘获取 |
18.2.4 禁用错误传递
语法:
try!
说明:其实就是把抛出错误转变为运行时断言
应用:确定throwing函数实际上在运行时不会抛出错误的才能使用。
注意:如果实际上抛出了错误,你会得到一个运行时错误(而不会传递错误)
1 | // 确定图片资源是存在的 |
18.3 指定清理操作
说明:使用
defer语句指定在即将离开当前代码块时执行一系列语句。
支持情景:不管是以何种方式离开当前代码块的
- 由于抛出错误而离开
- 诸如
return或者break的语句语法:由
defer关键字和要被延迟执行的语句组成
- 延迟执行的语句不能包含任何
控制转移语句(break或是return语句,或是抛出一个错误)- 延迟执行的操作会按照它们被指定时的顺序的
相反顺序执行
1 | // 处理文件 |